Appearance
《面向对象程序设计(Java)》期末试卷A (精选01)
一、选择题(共 20 题,每题 1.5 分,共 30 分)
1.运行名为 Test.class 的 Java 字节码文件,所用的 Java 命令是( )
- A.
javac Test.java - B.
javac Test.class - C.
java Test - D.
java Test.class
查看答案与解析
答案:C
解析:
javac是 Java 编译器,用于将.java源文件编译为.class字节码文件,A、B 错误。java是 Java 虚拟机启动命令,运行字节码文件时不需要加.class后缀,只需写类名。- 正确命令:
java Test,C 正确,D 错误。
难度: ⭐ 考点: #Java命令 #javac #java
💡 学习锦囊
📖 相关公式与知识点:
- javac:编译器,将
.java源文件编译为.class字节码文件 - java:虚拟机启动命令,运行字节码文件(不加
.class后缀)
易错点
java Test运行时不加.class后缀javac后面跟源文件名(带.java),java后面跟类名(不带后缀)
🔄 举一反三
- 如果源文件名为
HelloWorld.java,编译和运行的命令分别是什么?查看练习答案与解析
答案:编译
javac HelloWorld.java,运行java HelloWorld解析:javac 编译源文件需要带.java后缀,java 运行类不需要后缀。
2.下列不可作为 Java 语言标识符的是( )
- A.
a2 - B.
$2 - C.
_2 - D.
22
查看答案与解析
答案:D
解析: Java 标识符命名规则:
可以由字母、数字、下划线
_、美元符号$组成不能以数字开头
不能使用 Java 关键字
A:
a2以字母开头,合法 ✓B:
$2以 $ 开头,合法 ✓C:
_2以下划线开头,合法 ✓D:
22以数字开头,非法 ✗
难度: ⭐ 考点: #标识符 #命名规则
💡 学习锦囊
📖 相关公式与知识点:
- 标识符规则:字母/
_/$开头,不含关键字,区分大小写 - 不能以数字开头
易错点
$和_可以作为标识符开头- 数字不能作为标识符开头,但可以出现在中间
🔄 举一反三
- 下列哪个是合法的 Java 标识符?
- A.
class - B.
_name - C.
3abc - D.
my-name
查看练习答案与解析
答案:B 解析:A 是 Java 关键字;B 以下划线开头,合法;C 以数字开头,非法;D 含连字符,非法。
- A.
3.以下关于运算符优先级顺序的描述中正确的是( )
- A. 关系运算符 < 算术运算符 < 赋值运算符
- B. 赋值运算符 < 关系运算符 < 算术运算符
- C. 算术运算符 < 关系运算符 < 赋值运算符
- D. 赋值运算符 < 算术运算符 < 关系运算符
查看答案与解析
答案:B
解析: Java 运算符优先级(从高到低):算术运算符 > 关系运算符 > 赋值运算符
用"<"表示"优先级低于":赋值运算符 < 关系运算符 < 算术运算符
难度: ⭐⭐ 考点: #运算符优先级
💡 学习锦囊
📖 相关公式与知识点:
- 运算符优先级:算术 > 关系 > 逻辑 > 赋值
- 赋值运算符优先级最低
易错点
- 赋值运算符优先级最低
- 逻辑运算符介于关系运算符和赋值运算符之间
🔄 举一反三
- 表达式
a + b > c && d == e中,运算符的执行顺序是?查看练习答案与解析
答案:先
a+b,再>c和==e,最后&&解析:算术(+) → 关系(>, ==) → 逻辑(&&),按优先级从高到低执行。
4.getCustomerInfo() 方法如下,try 中可以捕获三种类型的异常,如果在该方法中产生了一个 IOException,将会输出什么结果( )
public void getCustomerInfo() {
try {
// do something that may cause an Exception
} catch (java.io.FileNotFoundException ex) {
System.out.print("FileNotFoundException!");
} catch (java.io.IOException ex) {
System.out.print("IOException!");
} catch (java.lang.Exception ex) {
System.out.print("Exception!");
}
}2
3
4
5
6
7
8
9
10
11
- A.
IOException! - B.
IOException!Exception! - C.
FileNotFoundException!IOException! - D.
FileNotFoundException!IOException!Exception!
查看答案与解析
答案:A
解析: 异常捕获的匹配规则:从上到下依次匹配,第一个匹配的 catch 块执行后,后面的 catch 块不再执行。
异常类的继承关系:FileNotFoundException → IOException → Exception
当产生 IOException 时:
FileNotFoundException是IOException的子类,不匹配 → 跳过IOException精确匹配 → 执行,输出IOException!Exception虽然也能匹配,但已被前面的 catch 捕获 → 不执行
难度: ⭐⭐ 考点: #异常处理 #异常捕获顺序
💡 学习锦囊
📖 相关公式与知识点:
- 异常捕获顺序:子类异常必须在父类异常之前
- 多 catch 块:从上到下匹配,第一个匹配的执行后不再继续
易错点
- 多个 catch 块只执行第一个匹配的,不会全部执行
- 子类异常必须写在父类异常之前,否则编译报错
🔄 举一反三
- 如果产生
FileNotFoundException,会输出什么?查看练习答案与解析
答案:
FileNotFoundException!解析:FileNotFoundException精确匹配第一个 catch 块,执行后不再继续。
5.声明成员变量时,如果不使用任何访问控制符,则以下哪种类型的类不能对该成员进行直接访问( )
- A. 同一类
- B. 同一包中的子类
- C. 同一包中的非子类
- D. 不同包中的子类
查看答案与解析
答案:D
解析: 不使用任何访问控制符时,成员的访问权限为默认(包访问权限/default):
| 访问者 | 能否访问 |
|---|---|
| 同一类 | ✓ |
| 同一包中的子类 | ✓ |
| 同一包中的非子类 | ✓ |
| 不同包中的子类 | ✗ |
| 不同包中的非子类 | ✗ |
难度: ⭐ 考点: #访问修饰符 #default权限
💡 学习锦囊
📖 相关公式与知识点:
- private:本类可访问
- default(无修饰符):本包可访问
- protected:本包 + 其他包的子类可访问
- public:所有类可访问
易错点
- default 权限不允许跨包访问,即使是子类也不行
- protected 允许跨包的子类访问,这是与 default 的关键区别
🔄 举一反三
- 如果成员用
protected修饰,不同包中的子类能否访问?查看练习答案与解析
答案:能 解析:protected 允许同包的所有类和不同包的子类访问。
6.对于下列代码:
String str1 = "java";
String str2 = "java";
String str3 = new String("java");
StringBuffer str4 = new StringBuffer("java");2
3
4
下列结论正确的是( )
- A.
str1 == str2 - B.
str1 == str4 - C.
str2 == str3 - D.
str3 == str4
查看答案与解析
答案:A
解析:== 比较的是引用(地址),equals() 比较的是内容。
str1 = "java"和str2 = "java":字符串字面量存储在字符串常量池中,相同内容共享同一对象,所以str1 == str2为 true,A 正确。str3 = new String("java"):new在堆内存中创建新对象,与常量池中的对象地址不同,str2 == str3为 false,C 错误。str4 = new StringBuffer("java"):StringBuffer 是不同类型,与 String 比较==必然为 false,B、D 错误。
难度: ⭐⭐ 考点: #String比较 #字符串常量池 #==与equals
💡 学习锦囊
📖 相关公式与知识点:
- String 常量池:字面量共享同一对象,
new创建新对象 ==:比较引用(地址)equals():比较内容
易错点
new String("java")创建新对象,与常量池中的"java"地址不同==比较地址,equals()比较内容
🔄 举一反三
- 以下代码输出什么?java
String s1 = "hello"; String s2 = new String("hello"); System.out.println(s1 == s2); System.out.println(s1.equals(s2));1
2
3
4查看练习答案与解析
答案:
false然后true解析:s1在常量池中,s2在堆内存中,==比较地址不同所以 false;equals()比较内容相同所以 true。
7.关于接口,下面的叙述错误的是( )
- A. 一个接口可以继承多个接口
- B. 一个类可以实现多个接口
- C. 抽象类在实现接口时,可以不实现该接口中声明的所有方法
- D. 抽象类在实现接口时,必须实现该接口中声明的所有方法
查看答案与解析
答案:D
解析:
- A 正确:接口支持多继承
- B 正确:类可以实现多个接口
- C 正确:抽象类实现接口时,可以只实现部分方法,未实现的方法仍为抽象方法
- D 错误:抽象类实现接口时,不需要实现所有方法
难度: ⭐⭐ 考点: #接口 #抽象类 #多继承
💡 学习锦囊
📖 相关公式与知识点:
- 接口多继承:接口可以继承多个接口
- 类多实现:一个类可以实现多个接口
- 抽象类实现接口:可以只实现部分方法
易错点
- 抽象类实现接口时不需要实现所有方法
- 具体类(非抽象类)实现接口时必须实现所有方法
🔄 举一反三
- 如果一个具体类实现了一个接口但没有实现所有方法,会怎样?
查看练习答案与解析
答案:编译报错 解析:具体类必须实现接口中的所有抽象方法,否则必须声明为抽象类。
8.以下程序运行的结果是( )
public class Test {
public int div(int a, int b) {
try {
return a / b;
} catch (Exception e) {
System.out.println("Exception");
} catch (NULLException e) {
System.out.println("NullException");
} catch (ArithmeticException e) {
System.out.println("ArithmeticException");
} finally {
System.out.println("finally");
}
return 0;
}
public static void main(String[] args) {
Test demo = new Test();
System.out.println("商是:" + demo.div(9, 10));
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- A.
Exception finally 商是:0 - B.
ArithmeticException finally 商是:0 - C.
finally 商是:0 - D. 编译报错
查看答案与解析
答案:D
解析: Java 异常捕获要求:子类异常必须写在父类异常之前,否则编译报错。
代码中 catch(Exception e) 写在最前面,而 ArithmeticException 是 Exception 的子类,后面的 catch(ArithmeticException e) 永远不可达,编译器报错。
此外,NullException 不是 Java 标准异常类(标准类为 NullPointerException),也会导致编译错误。
难度: ⭐⭐⭐ 考点: #异常处理 #catch顺序 #编译错误
💡 学习锦囊
📖 相关公式与知识点:
- catch 顺序:子类异常必须在父类异常之前
- 不可达代码:如果父类异常在前,子类异常的 catch 块永远不可达
易错点
- 子类异常必须写在父类异常之前,否则编译报错
NullException不是 Java 标准异常类
🔄 举一反三
- 将 catch 顺序调整为
ArithmeticException→Exception,调用div(9, 0)输出什么?查看练习答案与解析
答案:
ArithmeticException然后finally然后商是:0解析:9/0 抛出 ArithmeticException,匹配第一个 catch 输出 "ArithmeticException",finally 始终执行,最后 return 0 输出 "商是:0"。
9.在某个类中存在一个方法:void getSort(int x),以下能作为这个方法的重载的声明的是( )
- A.
public get(float x) - B.
int getSort(int y) - C.
double getSort(int x, int y) - D.
void get(int x, int y) {}
查看答案与解析
答案:C
解析: 方法重载要求:方法名相同,参数列表不同,与返回类型无关。
- A:方法名为
get,不是重载 ✗ - B:参数列表相同(形参名不同不算),仅返回类型不同,不是合法重载 ✗
- C:参数个数不同,合法重载 ✓
- D:方法名为
get,不是重载 ✗
难度: ⭐⭐ 考点: #方法重载 #参数列表
💡 学习锦囊
📖 相关公式与知识点:
- 方法重载:同名不同参,与返回类型无关
- 形参名不同不算重载
易错点
- 方法重载只看参数列表,不看返回类型和形参名
- 仅返回类型不同不是合法重载
🔄 举一反三
- 下列哪个是
public void show(int a)的合法重载?- A.
public int show(int b) - B.
public void show(double a) - C.
public void show() - D. B 和 C 都合法
查看练习答案与解析
答案:D 解析:A 参数相同仅返回类型不同,不合法;B 参数类型不同,合法;C 参数个数不同,合法。
- A.
10.以下哪句是错误的?( )
- A. 编译器会搜索要 import 的类的编译结果而不是源文件
- B. import 是要告诉编译器要 import 的包的信息
- C. import 是要把 import 的类的源代码插入到 import 语句所在的地方
- D. 编译器在编译的时候需要能访问得到 import 的类的编译结果文件
查看答案与解析
答案:C
解析:
- A 正确:编译器查找的是
.class文件 - B 正确:
import语句告诉编译器所需类的包路径信息 - C 错误:
import不会将源代码插入到当前位置,它只是告诉编译器去哪里找类 - D 正确:编译时需要能访问到被 import 类的
.class文件
难度: ⭐⭐ 考点: #import #编译机制
💡 学习锦囊
📖 相关公式与知识点:
- import 作用:告诉编译器类的包路径,不是插入源代码
- 与 C 的 #include 区别:
#include是插入源代码,import是指明路径
易错点
- Java 的
import不等于 C 语言的#include import不会将源代码插入到当前位置
🔄 举一反三
import java.util.*;的作用是什么?查看练习答案与解析
答案:告诉编译器在
java.util包中查找所需的类 解析:通配符*表示导入包中所有类,但不会实际加载所有类,只在需要时查找。
11.在 Java 中,关于 HashMap 类的描述,以下选项错误的是( )
- A. HashMap 使用键/值的形式保存数据
- B. HashMap 能够保证其中元素的顺序
- C. HashMap 允许将 null 用作键
- D. HashMap 允许将 null 用作值
查看答案与解析
答案:B
解析:
- A 正确:HashMap 基于哈希表,以键值对形式存储数据
- B 错误:HashMap 不保证元素的顺序。如需有序,应使用
LinkedHashMap或TreeMap - C 正确:HashMap 允许一个 null 键
- D 正确:HashMap 允许多个 null 值
难度: ⭐⭐ 考点: #HashMap #集合框架
💡 学习锦囊
📖 相关公式与知识点:
- HashMap:基于哈希表,键值对存储,不保证顺序
- LinkedHashMap:保持插入顺序
- TreeMap:按键的自然顺序排序
易错点
- HashMap 不保证元素顺序
- 如需有序 Map,使用 LinkedHashMap 或 TreeMap
🔄 举一反三
- 如果需要按插入顺序遍历 Map,应该使用哪个类?
查看练习答案与解析
答案:LinkedHashMap 解析:LinkedHashMap 在 HashMap 基础上维护了双向链表,保持键值对的插入顺序。
12.以下说法错误的是( )
- A. 静态方法可以直接访问本类的静态变量和静态方法
- B. 静态方法可以直接访问本类的非静态变量和非静态方法
- C. 非静态方法可以直接访问本类的静态变量和静态方法
- D. 非静态方法可以直接访问本类的非静态变量和非静态方法
查看答案与解析
答案:B
解析:
- A 正确:静态方法属于类,可以直接访问类的静态成员
- B 错误:静态方法不能直接访问非静态成员(非静态成员属于对象实例,需要先创建对象才能访问)
- C 正确:非静态方法中可以直接访问静态成员
- D 正确:非静态方法中可以直接访问同类的其他非静态成员
难度: ⭐⭐ 考点: #static #静态方法
💡 学习锦囊
📖 相关公式与知识点:
- 静态方法:属于类,可直接访问静态成员,不能直接访问非静态成员
- 非静态方法:属于对象,可直接访问静态和非静态成员
易错点
- 静态方法不能直接访问非静态成员,必须通过对象引用
- 非静态方法可以访问静态成员
🔄 举一反三
- 在静态方法中如何访问非静态成员?
查看练习答案与解析
答案:创建类的对象,通过对象引用访问 解析:如
MyClass obj = new MyClass(); obj.nonStaticMethod();
13.下列哪个选项定义的抽象类是正确的?( )
- A.
public abstract final class Car { abstract void move(); } - B.
public class abstract Car { abstract void move(); } - C.
public abstract class Car { abstract void drive(); } - D.
public abstract class Car { abstract void drive() { } }
查看答案与解析
答案:C
解析:
- A:
abstract和final不能同时修饰类 ✗ - B:关键字顺序错误,
abstract应在class之前 ✗ - C:语法正确 ✓
- D:抽象方法不能有方法体
{ }✗
难度: ⭐⭐ 考点: #抽象类 #抽象方法 #final
💡 学习锦囊
📖 相关公式与知识点:
- 抽象类:用
abstract修饰 - 抽象方法:只有声明,没有方法体
- abstract 与 final:不能同时修饰类
易错点
- 抽象方法不能有方法体
{ } abstract和final不能同时修饰类
🔄 举一反三
- 下列哪个抽象方法定义是正确的?
- A.
abstract void show() { } - B.
abstract void show(); - C.
void abstract show(); - D.
abstract show();
查看练习答案与解析
答案:B 解析:A 有方法体,错误;B 无方法体,正确;C 关键字顺序错误;D 缺少返回类型。
- A.
14.以下程序段输出的结果是( )
public class Test {
public static void main(String args[]) {
String str = "ABCDE";
str.substring(3);
str.concat("XYZ");
System.out.print(str);
}
}2
3
4
5
6
7
8
- A.
DE - B.
DEXYZ - C.
ABCDE - D.
CDEXYZ
查看答案与解析
答案:C
解析: String 是不可变的,substring() 和 concat() 方法都返回新字符串,不会修改原字符串。
如果需要修改,应写 str = str.substring(3); 或 str = str.concat("XYZ");。
难度: ⭐⭐ 考点: #String不可变 #substring #concat
💡 学习锦囊
📖 相关公式与知识点:
- String 不可变:
substring()、concat()等返回新对象,不修改原字符串 - 修改 String:需要赋值
str = str.substring(3);
易错点
- String 的所有修改方法都返回新对象,原对象不变
- 必须赋值才能改变引用
🔄 举一反三
- 以下代码输出什么?
String s = "hello"; s = s.toUpperCase(); System.out.println(s);查看练习答案与解析
答案:
HELLO解析:toUpperCase()返回新字符串,赋值给 s 后 s 指向新对象 "HELLO"。
15.在下面程序中的括号中,如下哪些代码可以创建并启动线程?( )
class MyRunnable implements Runnable {
public void run() {
// ...
}
}2
3
4
5
- A.
new Runnable(MyRunnable).start() - B.
new Thread(MyRunnable).run() - C.
new Thread(new MyRunnable()).start() - D.
new MyRunnable().start()
查看答案与解析
答案:C
解析: 创建并启动线程的正确方式:new Thread(Runnable对象).start()
- A:
Runnable是接口,不能这样使用 ✗ - B:调用
run()只是普通方法调用,不会启动新线程 ✗ - C:正确创建并启动线程 ✓
- D:
MyRunnable没有start()方法 ✗
难度: ⭐⭐ 考点: #线程创建 #Runnable #start方法
💡 学习锦囊
📖 相关公式与知识点:
- 线程创建:
new Thread(Runnable).start() - start() vs run():
start()启动新线程,run()只是普通方法调用
易错点
- 调用
run()不会启动新线程 Runnable对象没有start()方法,必须包装在Thread中
🔄 举一反三
- 继承 Thread 类创建线程的方式是什么?
查看练习答案与解析
javaclass MyThread extends Thread { public void run() { /* ... */ } } new MyThread().start();1
2
3
4解析:继承 Thread 类并重写
run()方法,直接调用start()启动线程。
16.如下程序输出( )
public class Test {
public static void main(String[] args) {
String s = "Java";
StringBuilder buffer = new StringBuilder(s);
change(s);
System.out.println(s);
}
private static void change(String s) {
s = s + " and HTML";
}
}2
3
4
5
6
7
8
9
10
11
- A.
Java - B.
Java and HTML - C.
and HTML - D. 什么都不显示
查看答案与解析
答案:A
解析: String 是不可变对象,且 Java 是值传递(引用类型的值是地址的副本)。
方法内的 s 是局部变量,重新赋值不影响 main 中的 s。输出 Java。
难度: ⭐⭐⭐ 考点: #值传递 #String不可变
💡 学习锦囊
📖 相关公式与知识点:
- Java 值传递:基本类型传值副本,引用类型传地址副本
- String 不可变:修改 String 会创建新对象
易错点
- Java 只有值传递,没有引用传递
- String 在方法内重新赋值不影响外部变量
🔄 举一反三
- 如果将
change方法的参数改为StringBuilder,输出什么?查看练习答案与解析
答案:
Java and HTML解析:StringBuilder 是可变对象,在方法内s.append(" and HTML")会修改原对象内容,外部变量能看到变化。
17.在使用 super 和 this 关键字时,以下描述正确的是( )
- A. 在子类构造方法中使用
super()显示调用父类的构造方法,super()必须写在子类构造方法的第一行,否则编译不通过 - B.
this()和super()可以同时出现在一个构造函数中 - C.
super()和this()不一定要放在构造方法内第一行 - D.
this()和super()可以在 static 环境中使用,包括 static 方法和 static 语句块
查看答案与解析
答案:A
解析:
- A 正确:
super()必须是子类构造方法的第一条语句 - B 错误:两者不能同时出现(都要求在第一行)
- C 错误:都必须在构造方法的第一行
- D 错误:都不能在 static 环境中使用
难度: ⭐⭐ 考点: #super #this #构造方法
💡 学习锦囊
📖 相关公式与知识点:
- super():调用父类构造方法,必须在第一行
- this():调用本类其他构造方法,必须在第一行
- 互斥:
super()和this()不能同时出现
易错点
super()和this()必须在构造方法第一行- 两者不能同时出现在同一个构造方法中
🔄 举一反三
- 如果子类构造方法中没有显式调用
super(),会发生什么?查看练习答案与解析
答案:编译器自动在第一行添加
super(),调用父类的无参构造方法 解析:如果父类没有无参构造方法,编译报错。
18.下面语句序列执行后,k 的值是什么?( )
int x = 6, y = 10, k;
switch (x % y) {
case 0: k = x * y;
case 6: k = x / y;
case 12: k = x - y;
default: k = x * y - x;
}2
3
4
5
6
7
- A. 60
- B. 5
- C. 0
- D. 54
查看答案与解析
答案:D
解析:x % y = 6 % 10 = 6,匹配 case 6。
关键:switch 语句中没有 break,会发生贯穿(fall-through):
case 6: k = x / y = 6 / 10 = 0
case 12: k = x - y = 6 - 10 = -4
default: k = x * y - x = 6 * 10 - 6 = 542
3
最终 k = 54。
难度: ⭐⭐⭐ 考点: #switch贯穿 #break #取模运算
💡 学习锦囊
📖 相关公式与知识点:
- switch 贯穿:没有 break 会从匹配 case 执行到底
- break:跳出 switch 语句
易错点
- switch 语句忘记写 break 导致贯穿
- 贯穿会从匹配的 case 开始执行所有后续 case 和 default
🔄 举一反三
- 如果每个 case 后都加上
break;,k 的值是什么?查看练习答案与解析
答案:0 解析:匹配 case 6,
k = 6 / 10 = 0,break 跳出 switch,k = 0。
19.下面关于缺省构造方法的描述中正确的是( )
- A. 当类中没有定义任何构造方法时,Java 编译器将为这个类创建缺省构造方法
- B. 缺省构造方法可以初始化其他方法中定义的变量
- C. Java 编译器会为所有的类创建缺省构造方法
- D. 如果在一个类中定义的构造方法都声明了参数,Java 编译器将为这个类创建一个缺省构造方法
查看答案与解析
答案:A
解析:
- A 正确:当类中没有定义任何构造方法时,编译器自动生成无参缺省构造方法
- B 错误:缺省构造方法只能初始化成员变量
- C 错误:如果类中已定义了构造方法,编译器不会再创建
- D 错误:已定义带参数的构造方法后,编译器不会再创建缺省构造方法
难度: ⭐⭐ 考点: #构造方法 #缺省构造方法
💡 学习锦囊
📖 相关公式与知识点:
- 缺省构造方法:无参,方法体为空
- 自动生成条件:类中没有定义任何构造方法时
易错点
- 如果自定义了构造方法,编译器不再提供默认无参构造
🔄 举一反三
- 如果类中定义了
MyClass(int x)但没有定义无参构造方法,new MyClass()能编译吗?查看练习答案与解析
答案:不能 解析:已定义有参构造方法后,编译器不再提供默认无参构造方法,需要手动添加。
20.下列哪个流类属于面向字符的输入流( )
- A.
BufferedWriter - B.
FileInputStream - C.
ObjectInputStream - D.
InputStreamReader
查看答案与解析
答案:D
解析:
- A:
BufferedWriter是输出流 ✗ - B:
FileInputStream是字节流 ✗ - C:
ObjectInputStream是字节流 ✗ - D:
InputStreamReader是字节流到字符流的桥梁,属于面向字符的输入流 ✓
难度: ⭐⭐ 考点: #IO流 #字符流 #字节流
💡 学习锦囊
📖 相关公式与知识点:
- 字节流:InputStream/OutputStream 及其子类
- 字符流:Reader/Writer 及其子类
- InputStreamReader:字节流 → 字符流的桥梁
易错点
- FileInputStream 是字节流,不是字符流
- InputStreamReader 是字符输入流
🔄 举一反三
- 下列哪个是面向字节的输出流?
- A.
FileReader - B.
FileWriter - C.
FileOutputStream - D.
BufferedReader
查看练习答案与解析
答案:C 解析:A、D 是字符输入流;B 是字符输出流;C 是字节输出流。
- A.
二、程序阅读及填空题(共 20 空,每空 2 分,共 40 分)
1. 请在空格中填写以下程序执行的结果:
public class IdentifyMyParts {
public static int x = 7;
public int y = 3;
}
public class Test {
public static void main(String[] args) {
IdentifyMyParts a = new IdentifyMyParts();
IdentifyMyParts b = new IdentifyMyParts();
a.y = 5;
b.y = 6;
a.x = 1;
b.x = 2;
System.out.println("a.y = " + a.y); // 屏幕输出为 (1)
System.out.println("b.y = " + b.y); // 屏幕输出为 (2)
System.out.println("a.x = " + a.x); // 屏幕输出为 (3)
System.out.println("b.x = " + b.x); // 屏幕输出为 (4)
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
查看答案与解析
(1) 答案:a.y = 5
(2) 答案:b.y = 6
(3) 答案:a.x = 2
(4) 答案:b.x = 2
解析:
y是实例变量(非 static),每个对象有独立副本:a.y = 5,b.y = 6。x是静态变量(static),所有对象共享同一份:最终x = 2。
难度: ⭐⭐ 考点: #静态变量 #实例变量 #static
💡 学习锦囊
📖 相关公式与知识点:
- 静态变量 vs 实例变量:静态变量被所有实例共享,实例变量每个对象独立
易错点
- 静态变量被所有实例共享,修改一个对象会影响所有对象
🔄 举一反三
- 以下代码输出什么?java
public class Test { static int count = 0; int id; Test() { count++; id = count; } public static void main(String[] args) { Test t1 = new Test(); Test t2 = new Test(); Test t3 = new Test(); System.out.println("t1.id=" + t1.id + ", t2.id=" + t2.id + ", count=" + count); } }1
2
3
4
5
6
7
8
9
10
11查看练习答案与解析
答案:
t1.id=1, t2.id=2, count=3解析:每次创建对象 count 自增并赋给 id。最终 count=3。
2. 请在空格中填写以下程序执行的结果:
public class java1 {
public static void main(String[] args) {
int arr[][] = {{34, 21, 45, 67, 20},
{23, 10, 3, 45, 76},
{22, 3, 79, 56, 50}};
int i = 0;
int j = 0;
int min = arr[0][0];
while (i < 3) {
while ( (5) ) {
if (arr[i][j] < min)
min = arr[i][j];
j++;
}
(6) ;
(7) ;
}
System.out.println("The min:" + min);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
查看答案与解析
(5) 答案:j < 5
(6) 答案:i++
(7) 答案:j = 0
解析: 程序功能:遍历二维数组找最小值。
- (5) 内层循环控制列索引,每行有 5 列,条件为
j < 5。 - (6) 行索引加 1:
i++。 - (7) 列索引重置为 0:
j = 0。
难度: ⭐⭐ 考点: #二维数组 #数组遍历 #求最小值
💡 学习锦囊
📖 相关公式与知识点:
- 二维数组遍历:外层循环行,内层循环列,注意索引重置
易错点
- 内层循环结束后必须重置列索引 j = 0
- 行索引 i++ 不能遗漏
🔄 举一反三
- 如何修改程序使其求最大值?
查看练习答案与解析
将
if (arr[i][j] < min)改为if (arr[i][j] > max),并将初始值设为int max = arr[0][0]。 解析:只需将比较方向反转即可。
3. 写出下列程序的输出结果:
class Exam31 {
public static void main(String[] args) {
int i = 1, j = 2, k = 3;
boolean b = -i > 1 && j++ < 2 && k-- < 3;
b = ++i > 1 || j-- < 2 && --k > 3;
b = ++i > 1 | j-- < 2 && --k > 3;
System.out.println("i=" + i); // 屏幕输出为 (8)
System.out.println("j=" + j); // 屏幕输出为 (9)
System.out.println("k=" + k); // 屏幕输出为 (10)
}
}2
3
4
5
6
7
8
9
10
11
查看答案与解析
(8) 答案:i=3
(9) 答案:j=1
(10) 答案:k=3
解析:
第一行:boolean b = -i > 1 && j++ < 2 && k-- < 3;
-i= -1,-1 > 1为 false,&&短路,j++ 和 k-- 不执行- i=1, j=2, k=3
第二行:b = ++i > 1 || j-- < 2 && --k > 3;
++i→ i=2,2 > 1为 true,||短路,j-- 和 --k 不执行- i=2, j=2, k=3
第三行:b = ++i > 1 | j-- < 2 && --k > 3;
++i→ i=3,3 > 1为 true|是非短路或,右边也要计算j-- < 2:j=2,2 < 2为 false,然后 j=1false && ...短路,--k不执行- i=3, j=1, k=3
难度: ⭐⭐⭐ 考点: #短路逻辑 #非短路或 #自增自减
💡 学习锦囊
📖 相关公式与知识点:
- 短路逻辑运算符:
&&和||会短路 - 非短路逻辑运算符:
&和|不会短路,两边都计算
易错点
|是非短路或,两边都会计算;||是短路或&&短路:左边为 false 不执行右边
🔄 举一反三
- 以下代码输出什么?java
int a = 5, b = 10; boolean r = (a > 3) | (b++ > 10); System.out.println("b=" + b);1
2
3查看练习答案与解析
答案:
b=11解析:|是非短路或,即使左边为 true,右边b++ > 10仍然执行,b 从 10 变为 11。
4. 请写出以下程序运行结果:
public class Main {
public static void main(String[] args) {
String s = "hello";
try {
s = s + "world";
s.toUpperCase();
String[] a = s.split("o");
System.out.println(a.length); // 屏幕输出为 (11)
} catch (Exception e) {
} finally {
System.out.print(s); // 屏幕输出为 (12)
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
查看答案与解析
(11) 答案:3
(12) 答案:helloworld
解析:
s = s + "world"; // s = "helloworld"
s.toUpperCase(); // 返回新字符串,但未赋值给 s,s 不变
String[] a = s.split("o"); // 按 "o" 分割 "helloworld"2
3
分割结果:a = ["hell", "w", "rld"],a.length = 3
finally 块输出 s,s 仍为 "helloworld"。
难度: ⭐⭐⭐ 考点: #String操作 #split #toUpperCase
💡 学习锦囊
📖 相关公式与知识点:
- String 不可变:
toUpperCase()返回新对象,不修改原字符串 - split() 方法:按分隔符分割字符串,返回数组
易错点
s.toUpperCase()不会修改 s,必须s = s.toUpperCase()才行split("o")分割后,分隔符本身不出现在结果中
🔄 举一反三
"a,b,,c".split(",")的结果数组长度是多少?查看练习答案与解析
答案:4 解析:分割为
["a", "b", "", "c"],长度为 4。注意空字符串也会作为元素。
5. 以下程序为类 Animal、Bird、Parrot 和 Test 的代码,请将程序填充完整,并填写输出结果。包结构为:com.an 中有 Animal 类;com.bd 中有 Bird、Parrot、Test 类。
// com.an 包
package com.an;
public (13) class Animal {
(14) String color;
public abstract void sound();
public Animal() {
color = "";
System.out.println("动物");
}
}
// com.bd 包
package com.bd;
public class Bird (15) Animal {
public Bird() {
color = "绿色";
System.out.println("鸟");
}
public void sound() {
System.out.println("鸟叫声");
}
public void sound(String msg) {
System.out.println("鸟发出的叫声:" + msg);
}
}
public class Parrot extends Bird {
public Parrot() {
System.out.println("鹦鹉");
}
public void sound() {
(16) ; // 调用父类的方法 sound()
}
}
public class Test {
public static void main(String[] args) {
Parrot p = new Parrot();
p.sound();
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
查看答案与解析
(13) 答案:abstract
(14) 答案:protected
(15) 答案:extends
(16) 答案:super.sound()
解析:
- (13) Animal 类有抽象方法
sound(),必须声明为abstract类。 - (14)
color需要被不同包的子类 Bird 访问,必须用protected修饰。 - (15) Bird 继承 Animal,使用
extends关键字。 - (16) 子类 Parrot 调用父类 Bird 的
sound()方法,使用super.sound()。
程序运行输出:
动物
鸟
鹦鹉
鸟叫声2
3
4
构造方法调用链:Parrot() → Bird() → Animal()(输出"动物")→ Bird()体(输出"鸟")→ Parrot()体(输出"鹦鹉")→ p.sound() → super.sound()(输出"鸟叫声")
难度: ⭐⭐⭐ 考点: #抽象类 #继承 #protected #super #构造方法调用链
💡 学习锦囊
📖 相关公式与知识点:
- 抽象类:含抽象方法的类必须声明为
abstract protected访问权限:允许跨包的子类访问- 构造方法调用链:创建子类对象时,先调用父类构造方法
易错点
- 不同包的子类访问父类成员需要
protected或public权限 - 构造方法调用顺序:父类先于子类
🔄 举一反三
- 如果将
color改为private,Bird 类能否访问?查看练习答案与解析
答案:不能 解析:private 成员只能在本类中访问,即使是子类也不能直接访问。
6. 在横线处填上合适的语句。
// MyException 为用户自定义异常类
public class MyException extends Exception {
}
class Person {
// 在下行空白处写出声明方法可能抛出 MyException 异常的语句
public void check(String strage) (17) {
int age = Integer.parseInt(strage);
if (age < 0) {
/* 在下行空白处填上抛出 MyException 异常对象的语句,
异常信息描述为"年龄不能为负数!" */
(18) ;
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
查看答案与解析
(17) 答案:throws MyException
(18) 答案:throw new MyException("年龄不能为负数!")
解析:
- (17) 方法声明可能抛出的异常,使用
throws关键字(在方法签名后)。 - (18) 实际抛出异常对象,使用
throw new关键字。
注意区分:
throws:声明异常(在方法签名中)throw:抛出异常(在方法体中)
难度: ⭐⭐ 考点: #异常抛出 #throws #throw
💡 学习锦囊
📖 相关公式与知识点:
- throws:声明异常(在方法签名中)
- throw:抛出异常(在方法体中)
易错点
throws在方法签名中声明异常,throw在方法体中抛出异常对象throw后面跟异常对象,throws后面跟异常类名
🔄 举一反三
- 如何在调用
check方法时处理异常?查看练习答案与解析
javatry { person.check("-5"); } catch (MyException e) { System.out.println(e.getMessage()); }1
2
3
4
5解析:使用 try-catch 捕获 MyException。
7. 如果一个整数 a 能被数 b 整除,则 b 是 a 的因子。下面是一个 Java 程序,它的功能是求给定整数 n 的所有因子的和 sum,请将程序补充完整。
public class Test {
public static void main(String args[]) {
int n = 6, sum = 0;
for (int k = 1; (19) ; k++) {
if ( (20) )
sum += k;
}
System.out.println(sum);
}
}2
3
4
5
6
7
8
9
10
查看答案与解析
(19) 答案:k <= n
(20) 答案:n % k == 0
解析:
- (19) 循环范围从 1 到 n,条件为
k <= n。 - (20) 判断 k 是否为 n 的因子:
n % k == 0。
当 n=6 时:因子为 1, 2, 3, 6,sum = 12。
难度: ⭐⭐ 考点: #因子 #取模运算 #循环
💡 学习锦囊
📖 相关公式与知识点:
- 因子:如果
n % k == 0,则 k 是 n 的因子 - 取模运算:
n % k求 n 除以 k 的余数
易错点
- 循环条件是
k <= n,不是k < n(n 本身也是因子) - 判断因子用
n % k == 0,不是k % n == 0
🔄 举一反三
- 求 n=12 的所有因子之和。
查看练习答案与解析
答案:28 解析:12 的因子为 1, 2, 3, 4, 6, 12,sum = 28。
三、编程题(共 3 题,每题 10 分,共 30 分)
1. 定义基类 Point(点)和派生类 Circle(圆),求圆的周长。Point 类有两个私有的数据成员 float x, y;Circle 类新增一个私有的数据成员半径 float r 和一个公有的求周长的函数 getCircumference();请编写 Point 和 Circle 类以及测试类。
查看答案与解析
答案:
class Point {
private float x;
private float y;
public Point(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}
class Circle extends Point {
private float r;
public Circle(float x, float y, float r) {
super(x, y);
this.r = r;
}
public float getCircumference() {
return 2 * 3.14159f * r;
}
}
public class Test {
public static void main(String[] args) {
Circle c = new Circle(0, 0, 5);
System.out.println("圆心:(" + c.getX() + ", " + c.getY() + ")");
System.out.println("半径:" + 5);
System.out.println("周长:" + c.getCircumference());
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
运行结果:
圆心:(0.0, 0.0)
半径:5
周长:31.41592
3
解析:
第一步:设计 Point 类 - 两个私有成员 float x, y 表示坐标,构造方法初始化,提供 getter 方法。
第二步:设计 Circle 类 - 继承 Point 类,新增私有成员 float r,构造方法调用 super(x, y),getCircumference() 计算周长 $C = 2\pi r$。
第三步:测试类 - 创建 Circle 对象,调用 getCircumference() 输出周长。
难度: ⭐⭐⭐ 考点: #继承 #super #圆的周长
💡 学习锦囊
📖 相关公式与知识点:
- 圆的周长:$C = 2\pi r$
- 继承:子类使用
extends继承父类,super()调用父类构造方法
易错点
- 子类构造方法必须调用
super(),且必须是第一条语句 - 父类的私有成员子类不能直接访问
🔄 举一反三
- 在此基础上,为 Circle 类添加求面积的方法
getArea()。查看练习答案与解析
javapublic float getArea() { return 3.14159f * r * r; }1
2
3解析:圆面积公式 $S = \pi r^2$,当 r=5 时,面积约为 78.53975。
2. 编写一个应用程序实现文件的拷贝,源文件(SourceFile.txt)及目标文件(TargetFile.txt)通过命令行参数得到。
查看答案与解析
答案:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("用法:java FileCopy <源文件> <目标文件>");
return;
}
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(args[0]);
fos = new FileOutputStream(args[1]);
int ch;
while ((ch = fis.read()) != -1) {
fos.write(ch);
}
System.out.println("文件拷贝完成!");
} catch (IOException e) {
System.out.println("文件操作出错:" + e.getMessage());
} finally {
try {
if (fis != null) fis.close();
if (fos != null) fos.close();
} catch (IOException e) {
System.out.println("关闭流出错:" + e.getMessage());
}
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
解析:
第一步:获取命令行参数 - args[0] 为源文件路径,args[1] 为目标文件路径
第二步:创建输入输出流 - FileInputStream 读取源文件,FileOutputStream 写入目标文件
第三步:循环读写 - fis.read() 逐字节读取,fos.write(ch) 写入
第四步:关闭流 - 在 finally 块中关闭流,确保资源释放
难度: ⭐⭐⭐ 考点: #文件IO #FileInputStream #FileOutputStream #命令行参数
💡 学习锦囊
📖 相关公式与知识点:
- 文件拷贝:
FileInputStream+FileOutputStream逐字节读写 - 命令行参数:
main(String[] args)中的args接收命令行参数 - 异常处理:try-catch-finally 确保流关闭
易错点
- 文件操作后必须在 finally 中关闭流
- 关闭流前要检查是否为 null
🔄 举一反三
- 使用 BufferedReader 和 BufferedWriter 实现文件拷贝。
查看练习答案与解析
javaimport java.io.*; public class FileCopy2 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader(args[0])); BufferedWriter bw = new BufferedWriter(new FileWriter(args[1])); String line; while ((line = br.readLine()) != null) { bw.write(line); bw.newLine(); } br.close(); bw.close(); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14解析:BufferedReader 提供
readLine()按行读取,BufferedWriter 提供write()和newLine()按行写入。
3. 编写一个完整的 Java Application 程序。包含类 Shape、类 Oval、类 Main,具体要求如下:
(1)编写一个抽象类 Shape 表示形状对象,包含以下成员:
- 属性:double 型常量 PI,其值为 3.1415926;
- 方法:包含
double area()和double perimeter()两个抽象方法;
(2)编写一个 Shape 类的子类 Oval,表示椭圆对象,包含以下成员:
- 属性:double 型私有成员变量 a,表示长轴半径;double 型私有成员变量 b,表示短轴半径;
- 方法:构造方法
Oval(double a, double b),用参数设置椭圆的长轴半径和短轴半径;构造方法Oval(),将椭圆的长轴半径和短轴半径都初始化为 0;成员方法double area(),重写 Shape 类中的 area 方法,返回椭圆的面积;成员方法double perimeter(),重写 Shape 类中的 perimeter 方法,返回椭圆的周长;方法public String toString(),将当前的椭圆对象转换成字符串形式,例如长轴半径为 10.0,短轴半径为 5,返回字符串"Oval(a:10.0, b:5.0)"。
(3)编写公共类 Main,实现如下功能: 1)创建一个长轴半径为 8.0,短轴半径为 6.0 的椭圆对象; 2)分别用 area 和 perimeter 方法,求出以上椭圆的面积和周长并输出,输出过程中要求使用到 toString 方法。
查看答案与解析
答案:
abstract class Shape {
final double PI = 3.1415926;
abstract double area();
abstract double perimeter();
}
class Oval extends Shape {
private double a;
private double b;
public Oval(double a, double b) {
this.a = a;
this.b = b;
}
public Oval() {
this.a = 0;
this.b = 0;
}
@Override
double area() {
return PI * a * b;
}
@Override
double perimeter() {
return 2 * PI * Math.sqrt((a * a + b * b) / 2);
}
@Override
public String toString() {
return "Oval(a:" + a + ", b:" + b + ")";
}
}
public class Main {
public static void main(String[] args) {
Oval oval = new Oval(8.0, 6.0);
System.out.println(oval.toString() + " 的面积:" + oval.area());
System.out.println(oval.toString() + " 的周长:" + oval.perimeter());
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
运行结果:
Oval(a:8.0, b:6.0) 的面积:150.7964448
Oval(a:8.0, b:6.0) 的周长:44.4248084394470552
解析:
第一步:设计 Shape 抽象类 - 定义常量 PI = 3.1415926,声明两个抽象方法 area() 和 perimeter()
第二步:设计 Oval 类 - 私有成员 a(长轴半径)和 b(短轴半径),两个构造方法,椭圆面积公式 $S = \pi \times a \times b$,椭圆周长近似公式 $P \approx 2\pi\sqrt{\frac{a^2 + b^2}{2}}$
第三步:Main 类测试 - 创建 Oval(8.0, 6.0) 对象,使用 toString() 输出对象信息,调用 area() 和 perimeter() 计算面积和周长
难度: ⭐⭐⭐ 考点: #抽象类 #方法重写 #椭圆面积 #椭圆周长 #toString
💡 学习锦囊
📖 相关公式与知识点:
- 椭圆面积:$S = \pi \times a \times b$(a 为长轴半径,b 为短轴半径)
- 椭圆周长近似:$P \approx 2\pi\sqrt{\frac{a^2 + b^2}{2}}$
- 抽象类:含抽象方法的类必须声明为
abstract,子类必须实现所有抽象方法 - toString():Object 类的方法,子类重写以返回对象的字符串表示
易错点
- 子类构造方法必须调用
super(),且必须是第一条语句 - 抽象类不能实例化,但可以有构造方法供子类调用
toString()方法必须用public修饰final常量在声明时必须初始化- 椭圆周长没有精确的初等公式,常用近似公式
🔄 举一反三
- 如果要添加一个 Circle 类(圆是椭圆的特殊情况,a=b=r),如何实现?
查看练习答案与解析
javaclass Circle extends Oval { public Circle(double r) { super(r, r); } }1
2
3
4
5解析:圆是长轴半径等于短轴半径的椭圆,继承 Oval 并在构造方法中传入相同的 r 值即可。